--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / backend / auto_propagation_manager.py
Displaying Raw • Download
meshchatx/src/backend/auto_propagation_manager.py e949ccf10a23b8a47a2530484eb282948c5b9992 (e949ccf1) Text, 4.71 KB
Tff7b72import T7ee787asyncio
Tff7b72import T7ee787time
Tff7b72import T7ee787RNS
Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backendT7ee787.T7ee787meshchat_utils Tff7b72import Te6edf3parse_lxmf_propagation_node_app_data
Tff7b72class T56d364AutoPropagationManagerTb4b4b4:
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3appTb4b4b4, Te6edf3contextTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffapp Tff7b72= Te6edf3app
Tff7b72selfTff7b72.Td2a8ffcontext Tff7b72= Te6edf3context
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Te6edf3contextTff7b72.Td2a8ffconfig
Tff7b72selfTff7b72.Td2a8ffdatabase Tff7b72= Te6edf3contextTff7b72.Td2a8ffdatabase
Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_last_check Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_check_interval Tff7b72= T79c0ff300 T8b949e# 5 minutes
Tff7b72def Td2a8ffstopTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72False
Tff7b72async Tff7b72def Td2a8ff_runTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# Wait a bit after startup to allow discovers to come in
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff10Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72= Tff7b72True
Tff7b72while Tff7b72selfTff7b72.Td2a8ffrunning Tff7b72and Tff7b72selfTff7b72.Td2a8ffcontextTff7b72.Td2a8ffrunningTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_preferred_propagation_node_auto_selectTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72await Tff7b72selfTff7b72.Td2a8ffcheck_and_update_propagation_nodeTb4b4b4(Tb4b4b4)
Tff7b72except Te6edf3asyncioTff7b72.Td2a8ffCancelledErrorTb4b4b4:
Tff7b72break
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffError in AutoPropagationManager for Tffd700{Tff7b72selfTff7b72.Td2a8ffcontextTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_check_intervalTb4b4b4)
Tff7b72async Tff7b72def Td2a8ffcheck_and_update_propagation_nodeTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
T8b949e# Get all propagation node announces
Te6edf3announces Tff7b72= Tff7b72selfTff7b72.Td2a8ffdatabaseTff7b72.Td2a8ffannouncesTff7b72.Td2a8ffget_announcesTb4b4b4(Te6edf3aspectTff7b72=Ta5d6ff"Ta5d6fflxmf.propagationTa5d6ff"Tb4b4b4)
Te6edf3nodes_with_hops Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3announce Tff7b72in Te6edf3announcesTb4b4b4:
Te6edf3dest_hash_hex Tff7b72= Te6edf3announceTb4b4b4[Ta5d6ff"Ta5d6ffdestination_hashTa5d6ff"Tb4b4b4]
Te6edf3dest_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3dest_hash_hexTb4b4b4)
T8b949e# Check if propagation is enabled for this node
Te6edf3node_data Tff7b72= Te6edf3parse_lxmf_propagation_node_app_dataTb4b4b4(Te6edf3announceTb4b4b4[Ta5d6ff"Ta5d6ffapp_dataTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3node_data Tff7b72or Tff7b72not Te6edf3node_dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72continue
Tff7b72if Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3dest_hashTb4b4b4)Tb4b4b4:
Te6edf3hops Tff7b72= Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhops_toTb4b4b4(Te6edf3dest_hashTb4b4b4)
Te6edf3nodes_with_hopsTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Te6edf3hopsTb4b4b4, Te6edf3dest_hash_hexTb4b4b4)Tb4b4b4)
T8b949e# Sort by hops (lowest first)
Te6edf3nodes_with_hopsTff7b72.Td2a8ffsortTb4b4b4(Tb4b4b4)
Te6edf3current_node Tff7b72= Tb4b4b4(
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_preferred_propagation_node_destination_hashTff7b72.Td2a8ffgetTb4b4b4(Tb4b4b4)
Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3nodes_with_hopsTb4b4b4:
Tff7b72return
T8b949e# Try nodes in order of hops until we find a reachable one
Tff7b72for Te6edf3hopsTb4b4b4, Te6edf3node_hex Tff7b72in Te6edf3nodes_with_hopsTb4b4b4:
T8b949e# If current node is already the best and we have it, check if we should keep it
Tff7b72if Te6edf3node_hex Tff7b72== Te6edf3current_nodeTb4b4b4:
T8b949e# We could probe it to be sure, but for now let's assume it's fine if it's the best
Tff7b72return
T8b949e# Before switching to a new "best" node, try to probe it to ensure it's actually reachable
Tff7b72tryTb4b4b4:
Te6edf3dest_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3node_hexTb4b4b4)
T8b949e# We use a short timeout for the probe
Tff7b72if Tff7b72await Tff7b72selfTff7b72.Td2a8ffprobe_nodeTb4b4b4(Te6edf3dest_hashTb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffAuto-propagation: Switching to better node Tffd700{Te6edf3node_hexTffd700}Ta5d6ff (Tffd700{Te6edf3hopsTffd700}Ta5d6ff hops) for Tffd700{Tff7b72selfTff7b72.Td2a8ffcontextTff7b72.Td2a8ffidentity_hashTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffappTff7b72.Td2a8ffset_active_propagation_nodeTb4b4b4(Te6edf3node_hexTb4b4b4, Te6edf3contextTff7b72=Tff7b72selfTff7b72.Td2a8ffcontextTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fflxmf_preferred_propagation_node_destination_hashTff7b72.Td2a8ffsetTb4b4b4(
Te6edf3node_hexTb4b4b4,
Tb4b4b4)
Tff7b72return
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ffAuto-propagation: Node Tffd700{Te6edf3node_hexTffd700}Ta5d6ff announced but probe failed, trying next...Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffAuto-propagation: Error probing node Tffd700{Te6edf3node_hexTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72async Tff7b72def Td2a8ffprobe_nodeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3destination_hashTb4b4b4)Tb4b4b4:
T8b949e"""Probes a destination to see if it's reachable."""
Tff7b72tryTb4b4b4:
T8b949e# We use the app's probe handler if available
Tff7b72if Tb4b4b4(
Tffa657hasattrTb4b4b4(Tff7b72selfTff7b72.Td2a8ffcontextTb4b4b4, Ta5d6ff"Ta5d6ffrnprobe_handlerTa5d6ff"Tb4b4b4)
Tff7b72and Tff7b72selfTff7b72.Td2a8ffcontextTff7b72.Td2a8ffrnprobe_handler
Tb4b4b4)Tb4b4b4:
T8b949e# Re-using the logic from RNProbeHandler but simplified
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)
T8b949e# Wait a bit for path
Te6edf3timeout Tff7b72= T79c0ff5
Te6edf3start Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72while Tb4b4b4(
Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72and Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72- Te6edf3start Tff7b72< Te6edf3timeout
Tb4b4b4)Tb4b4b4:
Tff7b72await Te6edf3asyncioTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.5Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72False
T8b949e# If we have a path, it's a good sign.
T8b949e# For propagation nodes, having a path is often enough to try using it.
Tff7b72return Tff7b72True
Tff7b72return Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tff7b72False
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────